package com.heima.commnet.service.impl;

import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.core.toolkit.StringUtils;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.heima.apis.article.IArticleClient;
import com.heima.apis.user.IUserClient;
import com.heima.apis.wemedia.IWeMediaClient;
import com.heima.commnet.mapper.CommentMapper;
import com.heima.commnet.service.CommentService;
import com.heima.common.constants.HotArticleConstants;
import com.heima.model.article.dtos.ArticleCommentDto;
import com.heima.model.behavior.UpdateArticleMess;
import com.heima.model.common.dtos.ResponseResult;
import com.heima.model.common.enums.AppHttpCodeEnum;
import com.heima.model.user.pojos.ApUser;
import com.heima.model.wemedia.pojos.ApCommentLike;
import com.heima.model.wemedia.pojos.WmNews;
import com.heima.model.wemedia.pojos.WmNewsComment;
import com.heima.model.wemedia.pojos.WmSensitive;
import com.heima.model.wemedia.vo.CommentVo;
import com.heima.user.service.ApUserService;
import com.heima.utils.common.SensitiveWordUtil;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.data.domain.Sort;
import org.springframework.data.mongodb.core.MongoTemplate;
import org.springframework.data.mongodb.core.query.Criteria;
import org.springframework.data.mongodb.core.query.Query;
import org.springframework.kafka.core.KafkaTemplate;
import org.springframework.stereotype.Service;
import thread.AppThreadLocalUtil;

import java.util.*;
import java.util.stream.Collectors;

@Service
public class CommentServiceImpl implements CommentService {
    @Autowired
    private MongoTemplate mongoTemplate;

    @Autowired
    private IWeMediaClient weMediaClient;

    @Autowired
    private IArticleClient articleClient;

    @Autowired
    private KafkaTemplate kafkaTemplate;

    @Autowired
    private IUserClient userClient;

    /**
     * 保存评论
     *
     * @param dto
     * @return
     */
    @Override
    public ResponseResult save(ArticleCommentDto dto) {
        //参数校验
        if (dto == null || dto.getArticleId() == null) {
            return ResponseResult.errorResult(AppHttpCodeEnum.PARAM_INVALID);
        }
        //判断登录
        ApUser apUser = AppThreadLocalUtil.getApUser();
        if (apUser == null) {
            return ResponseResult.errorResult(AppHttpCodeEnum.NEED_LOGIN);
        }
        //文章是否开启评论功能
        Boolean aBoolean = articleClient.isComment(dto.getArticleId());
        if (!aBoolean) return ResponseResult.errorResult(AppHttpCodeEnum.NO_OPERATOR_AUTH, "该文章禁止评论");
        //内容不能超过140字
        if (dto.getContent().length() > 140) {
            return ResponseResult.errorResult(AppHttpCodeEnum.PARAM_INVALID, "评论字数不能超过140");
        }
        //文本垃圾检测
        Map<String, Object> map = weMediaClient.handleSensitiveScan(dto.getContent());
        if (map.get("flag").equals(false))
            return ResponseResult.errorResult(AppHttpCodeEnum.PARAM_INVALID, (String) map.get("msg"));
        //保存评论
        WmNewsComment apComment = new WmNewsComment();
        apComment.setAuthorId(apUser.getId());
        apComment.setContent(dto.getContent());
        apComment.setCreatedTime(new Date());
        apComment.setEntryId(dto.getArticleId());
        String name = userClient.getById(apUser.getId());
        apComment.setAuthorName(name);
        apComment.setLikes(0);
        apComment.setReply(0);
        apComment.setType(0);
        apComment.setFlag(0);
        mongoTemplate.save(apComment);
        //kafka
        UpdateArticleMess mess = new UpdateArticleMess();
        mess.setAdd(1);
        mess.setArticleId(dto.getArticleId());
        mess.setType(UpdateArticleMess.UpdateArticleType.COMMENT);
        kafkaTemplate.send(HotArticleConstants.HOT_ARTICLE_SCORE_TOPIC, JSON.toJSONString(mess));
        return ResponseResult.okResult(AppHttpCodeEnum.SUCCESS);
    }

    /**
     * 点赞评论
     *
     * @param dto
     * @return
     */
    @Override
    public ResponseResult like(ArticleCommentDto dto) {
        //参数校验
        if (dto == null || StringUtils.isBlank(dto.getCommentId())) {
            return ResponseResult.errorResult(AppHttpCodeEnum.PARAM_INVALID);
        }
        ApUser apUser = AppThreadLocalUtil.getApUser();
        if (apUser == null) {
            return ResponseResult.errorResult(AppHttpCodeEnum.NEED_LOGIN);
        }
        Integer id = apUser.getId();

        return commentLike(dto, id);
    }

    @Override
    public ResponseResult commentLike(ArticleCommentDto dto, Integer id) {
        WmNewsComment newsComment = mongoTemplate.findById(dto.getCommentId(), WmNewsComment.class);
        if (newsComment!=null&& dto.getOperation() == 0) {
            //保存点赞记录
            ApCommentLike apCommentLike = new ApCommentLike();
            apCommentLike.setAuthorId(id);
            apCommentLike.setCommentId(dto.getCommentId());
            mongoTemplate.save(apCommentLike);
            //增加点赞数量
            newsComment.setLikes(newsComment.getLikes() == null ? 1 : newsComment.getLikes() + 1);
            mongoTemplate.save(newsComment);
        } else {
            //删除点赞数据
            mongoTemplate.remove(Query.query(Criteria.where("commentId").is(dto.getCommentId()).and("authorId").is(id)), ApCommentLike.class);
            //减少点赞数量
            newsComment.setLikes(newsComment.getLikes() == null ? 0 : newsComment.getLikes() - 1);
            mongoTemplate.save(newsComment);
        }
        Map<String, Object> result = new HashMap<>();
        result.put("likes", newsComment.getLikes());
        return ResponseResult.okResult(result);
    }


    /**
     * 加载评论列表
     *
     * @param dto
     * @return
     */
    @Override
    public ResponseResult load(ArticleCommentDto dto) {
        //参数校验
        if (dto == null || dto.getArticleId() == null) {
            return ResponseResult.errorResult(AppHttpCodeEnum.PARAM_INVALID);
        }
        //条件查询评论
        //当前文章id,创建时间倒序,分页,默认10条
        List<WmNewsComment> wmNewsComments =
                mongoTemplate.find(Query.query(Criteria.where("entryId").is(dto.getArticleId()).and("createdTime").lt(dto.getMinDate()))
                        .with(Sort.by(Sort.Direction.DESC, "createdTime"))
                        .limit(10).skip(0), WmNewsComment.class);
        //登录
        ApUser apUser = AppThreadLocalUtil.getApUser();
        if (apUser == null) {
            //未登录,直接返回评论列表
            return ResponseResult.okResult(wmNewsComments);
        }
        //登录了,高亮展示用户点赞
        //评论列表中,被点赞的评论+用户id都一致 高亮
        List<String> commentId = wmNewsComments.stream().map(WmNewsComment::getId).collect(Collectors.toList());
        List<ApCommentLike> apCommentLikes = mongoTemplate.find(Query.query(Criteria.where("authorId").is(apUser.getId()).and("commentId").in(commentId)), ApCommentLike.class);
        if (apCommentLikes.size() == 0) {
            return ResponseResult.okResult(wmNewsComments);
        }
        //登录用户点赞的评论 operation设置为0
        List<CommentVo> list = new ArrayList<>();
        for (WmNewsComment wmNewsComment : wmNewsComments) {
            CommentVo vo = new CommentVo();
            BeanUtils.copyProperties(wmNewsComment, vo);
            for (ApCommentLike apCommentLike : apCommentLikes) {
                if (wmNewsComment.getId().equals(apCommentLike.getCommentId())) {
                    vo.setOperation((short) 0);
                }
            }
            list.add(vo);
        }
        //返回评论集合
        return ResponseResult.okResult(list);
    }


}
